import { ref, Ref, ComputedRef, unref, computed, watch, toRaw } from 'vue';
import type { BasicColumn, BasicTableProps } from '../types/table';
import { isEqual, cloneDeep } from 'lodash-es';
import { isArray, isString } from '@/utils/is';
import { usePermission } from '@/hooks/web/usePermission';
import { isString, isBoolean, isFunction } from "@/utils/is";
import { ActionItem } from "@/components/Table";

export function useColumns(propsRef: ComputedRef<BasicTableProps>) {
    const columnsRef = ref(unref(propsRef).columns) as unknown as Ref<BasicColumn[]>;
    let cacheColumns = unref(propsRef).columns;

    const getColumnsRef = computed(() => {
        const columns = cloneDeep(unref(columnsRef));

        handleActionColumn(propsRef, columns);
        if (!columns) return [];
        return columns;
    })

    const { hasPermission } = usePermission();

    function isIfShow(action: ActionItem): boolean {
        const ifShow = action.ifShow;

        let isIfShow = true;

        if (isBoolean(ifShow)) {
            isIfShow = ifShow;
        }
        if (isFunction(ifShow)) {
            isIfShow = ifShow(action);
        }
        return isIfShow;
    }

    const getPageColumns = computed(() => {
        const pageColumns = unref(getColumnsRef);
        const columns = cloneDeep(pageColumns);
        return columns.filter((column) => {
            return hasPermission(column.auth) && isIfShow(column);
        })
    })

    watch(
        () => unref(propsRef).columns,
        (columns) => {
            columnsRef.value = columns;
            cacheColumns = columns;
        }
    );

    function handleActionColumn(propsRef: ComputedRef<BasicTableProps>, columns: BasicColumn[]) {
        const { actionColumn } = unref(propsRef);
        if (!actionColumn) return;
        columns.push({
            ...actionColumn
        });
    }

    //设置
    function setColumns(columnList: string[]) {
        const columns: any[] = cloneDeep(columnList);
        if (!isArray(columns)) return;

        if (!columns.length) {
            columnsRef.value = [];
            return;
        }
        const cacheKeys = cacheColumns.map((item) => item.key);
        //针对拖拽排序
        if (!isString(columns[0])) {
            columnsRef.value = columns;
        } else {
            const newColumns: any[] = []
            cacheColumns.forEach(item => {
                if (columnList.includes(item.key)) {
                    newColumns.push({ ...item })
                }
            })
            if (!isEqual(cacheKeys, columns)) {
                newColumns.sort((prev, next) => {
                    return (
                        cacheKeys.indexOf(prev.key) - cacheKeys.indexOf(next.key)
                    );
                });
            }
            columnsRef.value = newColumns
        }
    }

    //获取
    function getColumns() {
        let columns = toRaw(unref(getColumnsRef));
        return columns.map(item => {
            return { ...item, title: item.title, key: item.key, fixed: item.fixed || undefined }
        })
    }

    //获取原始
    function getCacheColumns(isKey?: boolean): any[] {
        return isKey ? cacheColumns.map(item => item.key) : cacheColumns;
    }

    //更新原始数据单个字段
    function setCacheColumnsField(dataIndex: string | undefined, value: Partial<BasicColumn>) {
        if (!dataIndex || !value) {
            return;
        }
        cacheColumns.forEach((item) => {
            if (item.key === dataIndex) {
                Object.assign(item, value);
                return;
            }
        });
    }

    return {
        getColumnsRef,
        getCacheColumns,
        setCacheColumnsField,
        setColumns,
        getColumns,
        getPageColumns
    };
}
